package org.example.lottery_system.service.impl;

import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import org.example.lottery_system.common.errorcode.ServiceErrorCodeConstants;
import org.example.lottery_system.common.exception.ServiceException;
import org.example.lottery_system.common.utils.JWTUtil;
import org.example.lottery_system.common.utils.RegexUtil;
import org.example.lottery_system.controller.param.UserPasswordLoginParam;
import org.example.lottery_system.controller.param.UserRegisterParam;
import org.example.lottery_system.dao.UserMapper;
import org.example.lottery_system.dao.dataObject.Encrypt;
import org.example.lottery_system.dao.dataObject.UserDO;
import org.example.lottery_system.dao.pojo.UserInfo;
import org.example.lottery_system.service.dto.UserLoginDto;
import org.example.lottery_system.service.dto.UserRegisterDto;
import org.example.lottery_system.service.enums.UserIDentityEnum;
import org.example.lottery_system.service.UserService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService {
    @Resource
private UserMapper userMapper;
    @Override
    public UserRegisterDto userRegister(UserRegisterParam param) {
        //校验信息
        UserDO userDO = new UserDO();
        userDO.setUserName(param.getName());
        userDO.setIdentity(param.getIdentity());
        userDO.setEmail(param.getMail());
        userDO.setPhoneNumber(new Encrypt(param.getPhoneNumber()));
        if (StringUtils.hasText(param.getPassword())){
            userDO.setPassword(param.getPassword());
        }
        //保存数据
        userMapper.insert(userDO);
        //返回数据
        UserRegisterDto userRegisterDto = new UserRegisterDto();
        userRegisterDto.setUserId(userDO.getId());

        return userRegisterDto;
    }

    @Override
    public void checkRegisterInfo(UserRegisterParam param) {
        //校验参数是否为空
        if (null == param){
            throw new ServiceException(ServiceErrorCodeConstants.REGISTER_INFO_IS_EMPTY);
        }
        //校验邮箱格式
        if (!RegexUtil.checkMail(param.getMail())){
            throw new ServiceException(ServiceErrorCodeConstants.MAIL_EMPTY);
        }
        //校验电话格式
        if (RegexUtil.checkMobile(param.getPhoneNumber())) {
            throw new ServiceException(ServiceErrorCodeConstants.PHONE_EMPTY);
        }
        //校验权限是否为正确的权限
        if (UserIDentityEnum.forname(param.getIdentity()) == null){
            throw new ServiceException(ServiceErrorCodeConstants.IDENTITY_EMPTY);
        }
        //校验是否是管理员是否需要密码
        if (param.getIdentity().equalsIgnoreCase(UserIDentityEnum.ADMIN.name())
        && !StringUtils.hasText(param.getPassword())){
            throw new ServiceException(ServiceErrorCodeConstants.PASSWORD_IS_EMPTY);
        }
        //校验管理员密码格式
        if (StringUtils.hasText(param.getPassword())&&!RegexUtil.checkPassword(param.getName())){
            throw new ServiceException(ServiceErrorCodeConstants.PASSWORD_ERROR);
        }
        //校验手机号是否被使用
        if (!checkMailUsed(param.getMail())){
            throw new ServiceException(ServiceErrorCodeConstants.PHONENUMBER_USED_ERROR);
        }
        //校验邮箱是否被使用
        if (!checkMailUsed(param.getPhoneNumber())){
            throw new ServiceException(ServiceErrorCodeConstants.MAIL_USED_ERROR);
        }
    }
    public boolean checkMailUsed(String email) {
        LambdaQueryWrapper<UserInfo> eq = new LambdaQueryWrapper<UserInfo>().select(UserInfo::getEmail)
                .eq(UserInfo::getEmail, email);
        List<String> mails = userMapper.findEmailByEmail(email);
        if (mails.size() == 0){
            return true;
        }
        return false;
    }
    public boolean checkPhoneNumberUsed(String PhoneNumber) {
        LambdaQueryWrapper<UserInfo> eq = new LambdaQueryWrapper<UserInfo>().select(UserInfo::getEmail)
                .eq(UserInfo::getPhoneNumber,PhoneNumber);
        int i = userMapper.countByPhone(new Encrypt(PhoneNumber));
        if (i == 0){
            return true;
        }
        return false;
    }

    public UserLoginDto login(UserPasswordLoginParam param) {
        UserLoginDto userLoginDto = null;
        UserDO userDO = null;
        if(param == null){
            throw new ServiceException(ServiceErrorCodeConstants.LOGIN_USED_ERROR);
        }
        if(RegexUtil.checkMail(param.getLoginName())){
            userDO = userMapper.selectByEmail(param.getLoginName());
        }
        else if(RegexUtil.checkMobile(param.getLoginName())){
            userDO = userMapper.selectByPhoneNumber(new Encrypt(param.getLoginName()));
        }
        else{
            throw new ServiceException(ServiceErrorCodeConstants.LOGIN_NOTEXSIT_ERROR);
        }
        if(userDO == null){
            throw new ServiceException(ServiceErrorCodeConstants.LOGIN_USED_ERROR);
        }
        else if(StringUtils.hasText(param.getMandatoryIdentity())&&!userDO.getIdentity().equalsIgnoreCase(param.getMandatoryIdentity())){

                throw new ServiceException(ServiceErrorCodeConstants.PERMISSION_ERROR);
        }
        else if(!param.getPassword().equals(userDO.getPassword())){
            System.out.println(DigestUtil.sha256Hex(param.getPassword()));
            System.out.println(userDO.getPassword());
            throw new ServiceException(ServiceErrorCodeConstants.PASSWORD_ERROR);
        }
        Map<String,Object> claim = new HashMap<>();
        claim.put("id",userDO.getId());
        claim.put("identity",userDO.getIdentity());
        String s = JWTUtil.genJwt(claim);
        userLoginDto = new UserLoginDto();
        userLoginDto.setToken(s);
        userLoginDto.setIdentity(UserIDentityEnum.forname(userDO.getIdentity()));
        return userLoginDto;
    }
}
